/**
	血糖仪器申请

*/	
public without sharing class BloodApplication2Controller {


	public String msg {private set ;get;}
	public String backId {private set; get;}
	public String dataJson {private set; get;}
    public String saveJson { set; get;}

	public Boolean isSuc {private set; get;}
	public Boolean isErr {private set; get;}

	// public String type ;//血糖仪申请的类型
    private BloodSugarOrder__c bos ; //血糖仪申请
    private Map<String,DataUtil.SObjectBean>   stageObjectMap ;
    public Boolean isNew {private set; get;}

    public Boolean isSync {private set; get; }


    public BloodApplication2Controller() {
        backId = System.currentPageReference().getParameters().get('id');
        bos = new BloodSugarOrder__c();
        stageObjectMap = new Map<String,DataUtil.SObjectBean>();
        isNew = false;
        isSync = System.currentPageReference().getParameters().get('sync') != null ;

    }
     public BloodApplication2Controller(ApexPages.StandardController con ) {

         backId = System.currentPageReference().getParameters().get('id');
        bos = new BloodSugarOrder__c();
        stageObjectMap = new Map<String,DataUtil.SObjectBean>();
        isNew = false;
        isSync = System.currentPageReference().getParameters().get('sync') != null ;


    }

    public void init(){

    	try {
            Map<String,Object> dataMap = new Map<String,Object>();
    		if(backId == null || Id.valueOf(backId).getSObjectType() != BloodSugarOrder__c.SObjectType ){
    			//新建
                dataMap.put('type', getTypes());
                isNew = true;
    		}else {
    			//编辑
    			bos = [select Id,Owner.Name,RecordTypeId ,RecordType.Name ,RecordType.DeveloperName,Status__c,Account__c,Account__r.Name , Opportunities__c,Opportunities__r.Name, Contract__c,Contract__r.Name,
                DocumentTypes__c,Company__c,ReceiverTelephone__c,FollowupProcessing__c,Account__r.AccountNumber,Address__c,ReceivingCustomer__c,ReceivingCustomer__r.AccountNumber, Synchronization__c,PhysicalDelivery__c,
                ReasonList__c,Reason__c
                 from BloodSugarOrder__c where Id=:backId];

                dataMap.put('recordType',bos.getSObject('RecordType'));
                if(isSync){
                     dataJson = EncodingUtil.urlEncode(JSON.serialize(dataMap), 'UTF-8');
                    return;
                }
                if(bos.Status__c == '审批成功' || bos.Status__c == '审批中') throw new DmlException(bos.Status__c +' 不能修改!');
                dataMap.put('detail',getDetails());
                

    		}
            dataMap.put('combox',ImportObject.getPicklistValues('BloodSugarOrderDetail__c', 'Reason__c', false));

             //字段
             Map<String,Set<String>> fieldsmap = getFields();
             //字段详情
             Map<String, List<DataUtil.FieldBean>> fbMap = DataUtil.getFieldsBean(fieldsmap,stageObjectMap);
            //字段赋值
             Map<String,List<DataUtil.FieldBean>> fields = DataUtil.setFieldsValue(fbMap,DataUtil.getBaseInfo(fbMap,stageObjectMap) );
            
            dataMap.put('base',fields);
            dataMap.put('search',getDetailFromProduct());

            dataMap.put('baseObject',DataUtil.getBaseObjectMap(stageObjectMap));

            dataJson = EncodingUtil.urlEncode(JSON.serialize(dataMap), 'UTF-8');

    	
    	}catch (Exception e) {
    	    isErr = true;
            ApexPages.addMessage( new ApexPages.Message(ApexPages.Severity.ERROR ,e.getMessage()+e.getStackTraceString()));
    	}


    	
    }

    private List<Object> getTypes(){

        List<Object> tmp = new List<Object>();
        for(RecordType r : [select  Name ,DeveloperName from  RecordType  where SobjectType = 'BloodSugarOrder__c' ]){
            tmp.add( r.getPopulatedFieldsAsMap());
        }
        return tmp;

    }



    public void search(){

        Map<String,Object> searchMap = (Map<String,Object>)JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson, 'UTF-8'));
        String stype = (String)searchMap.get('SObject');

        if(stype == 'opp')searchOpp(searchMap);
        if(stype == 'account')searchAccount(searchMap);
        if(stype == 'contract')searchContract(searchMap);


    }

    public void searchProduct(){


        Map<String,Object> searchMap = (Map<String,Object>)JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson, 'UTF-8'));
        String stype = (String)searchMap.get('recordType');
         List<Object> tmp = new List<Object> ();

        if(stype == 'SalesmenCollect' || stype == 'Give'){


            for ( Product__c ip : [select Id, Name ,NCCode__c,Brand__c,SerialNo__c,MatchingReagents__c,MatchingReagents__r.Name ,MatchingReagents__r.NCCode__c,MatchingReagents__r.Brand__c,MatchingReagents__r.SerialNo__c 
                from  Product__c where  MatchingReagents__c != null  ]) {
                Product__c regent = (Product__c)ip.getSObject('MatchingReagents__r');
                tmp.add(new BloodBeanOnly(ip  ));
                tmp.add(new BloodBeanOnly(regent));

            }
        }else if(stype == 'Replacement'){
            String accId = (String)searchMap.get('accId');

            for (Product__c cp  :Database.query('select Id ,Name,NCCode__c,Brand__c,SerialNo__c from Product__c where Id in  (select  Product__c from ContractProduct__c where (CoCustomer__c=\''+accId+'\'  or Contract__r.Account__c =\''+accId+'\' )   and Product__r.MatchingReagents__c != null)  ') ) {
                tmp.add(new BloodBeanOnly(cp  ));
            }

         }else {

            for ( Product__c ip : [select Id,NCCode__c,Brand__c,SerialNo__c, Name,zl__c ,MatchingReagents__c,MatchingReagents__r.Name ,MatchingReagents__r.NCCode__c , MatchingReagents__r.Zl__c   
                from  Product__c where  MatchingReagents__c != null  ]) {
                Product__c regent = (Product__c)ip.getSObject('MatchingReagents__r');
                tmp.add(new BloodBean(ip,regent ));

            }
         }

        dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');

        
    }
    public void searchAccount( Map<String,Object> searchMap){

        String sql = 'select Id,Name from Account  where RecordType.DeveloperName != \'Maccura\' ';

        if(String.isNotBlank((String) searchMap.get('Name'))) sql+= ' and  Name like \'%'+searchMap.get('Name')+'%\' ';
        sql += ' limit 20 ';
        List<Object> tmp = new List<Object>();
        for (Account acc  : Database.query(sql) ) {
            tmp.add(acc.getPopulatedFieldsAsMap());
        }
        dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');

    }

     public void searchOpp( Map<String,Object> searchMap){


        String sql = 'select Id,Name,OppNo__c from Opportunity  where Is_merged__c = false and AccountId  = \''+searchMap.get('accId')+'\'  and  StageName != \'合同签订\'  and StageName != \'失败\' ';
      

        if(String.isNotBlank((String) searchMap.get('Name'))) sql+= ' and  Name like \'%'+searchMap.get('Name')+'%\' ';
        if(String.isNotBlank((String) searchMap.get('OppNo__c'))) sql+= ' and  OppNo__c like \'%'+searchMap.get('OppNo__c')+'%\' ';
        sql += ' limit 20 ';
        List<Object> tmp = new List<Object>();
        for (Opportunity acc  : Database.query(sql) ) {
            tmp.add(acc.getPopulatedFieldsAsMap());
        }
        dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');



    }

     public void searchContract( Map<String,Object> searchMap){

      

        String sql = 'select Id,Name ,ContractNum__c from Contract__c  where  Status__c = \'已生效\' and  Stopped__c = false and   Account__c  = \''+searchMap.get('accId')+'\' and Id in (select Contract__c from ContractProduct__c where Product__r.MatchingReagents__c != null  and Contract__r.Account__c  = \''+searchMap.get('accId')+'\') ';

        if(String.isNotBlank((String) searchMap.get('Name'))) sql+= ' and  Name like \'%'+searchMap.get('Name')+'%\' ';
        if(String.isNotBlank((String) searchMap.get('ContractNum__c'))) sql+= ' and  ContractNum__c like \'%'+searchMap.get('ContractNum__c')+'%\' ';

        sql += ' limit 20 ';
                System.debug(sql);

        List<Object> tmp = new List<Object>();
        for (Contract__c acc  : Database.query(sql) ) {
            tmp.add(acc.getPopulatedFieldsAsMap());
        }
        dataJson = EncodingUtil.urlEncode(JSON.serialize(tmp), 'UTF-8');

        
    }



    public Map<String,Set<String>>  getFields(){
        Map<String,Set<String>> fieldsMap  = new  Map<String,Set<String>>();
        
            DataUtil.SObjectBean sb = new DataUtil.SObjectBean();

            sb.title ='';
            sb.objname = 'BloodSugarOrder__c';
            sb.stype = DataUtil.getSObjectType('BloodSugarOrder__c');
            if(!isNew)sb.idvalue = bos.Id;
            sb.type = 'base';
            if(!isNew)sb.condition = ' where Id =\''+bos.Id+'\'';
            stageObjectMap.put('BloodSugarOrder__c',sb );
            Set<String>  fields = new Set<String>{'Account__c','ReceivingCustomer__c','Opportunities__c','Contract__c','Policy__c','Reason__c','Address__c','ReceiverTelephone__c','ReasonList__c','Company__c' ,'Reason__c' ,'UsageTime__c','ProblemDate__c','ProblemDescription__c', 'PhysicalDelivery__c'};
           // if(bos.FromOpp__c != true) fields.remove('Opportunities__c');
           // if(bos.FromOpp__c != true) fields.add('Contract__c');
            fieldsMap.put('BloodSugarOrder__c', fields);
        
        return fieldsMap;
    }


    public List<BloodBean> getDetailFromProduct(){
        List<BloodBean> tmp = new List<BloodBean> ();

        for ( Product__c ip : [select Id,NCCode__c,Brand__c,SerialNo__c, Name,zl__c ,MatchingReagents__c,MatchingReagents__r.Name ,MatchingReagents__r.NCCode__c , MatchingReagents__r.Zl__c   
            from  Product__c where  MatchingReagents__c != null  ]) {
            Product__c regent = (Product__c)ip.getSObject('MatchingReagents__r');
            tmp.add(new BloodBean(ip,regent ));

        }
        return tmp; 
    }

    public List<Object> getDetails(){
        List<Object> tmp = new List<Object>();
        if(!isNew){

            for(BloodSugarOrderDetail__c bor : [select Id,DistributionProduct__c, DistributionProduct__r.Name ,FuselageNumber__c,Remark__c,
                Product__c,Product__r.Name,Product__r.zl__c,DistributionProduct__r.NCCode__c,DistributionProduct__r.Brand__c,DistributionProduct__r.SerialNo__c , CountT__c,OrderNumber__c,DistributionProductNumber__c,DistributionMax__c ,Reason__c 
             from BloodSugarOrderDetail__c where BloodSugarOrder__c =: backId]){

               if(bos.RecordType.DeveloperName == 'SalesmenCollect'  ||  bos.RecordType.DeveloperName== 'Give' ||  bos.RecordType.DeveloperName == 'Replacement'){
                    tmp.add(new BloodBeanOnly(bor));
               } else{
                    tmp.add(new BloodBean(bor));
               }

            }
        }
        return tmp;
    }


    public void save(){

        msg = '';
        Map<String,Object> saveMap = (Map<String,Object>) JSON.deserializeUntyped(EncodingUtil.urlDecode(saveJson, 'UTF-8'));

        Map<String,Set<String>> fieldsMap = getFields();
        Map<String,DataUtil.FieldBean> fbeanMap = DataUtil.getFieldsInfo(BloodSugarOrder__c.SObjecttype,fieldsMap.get('BloodSugarOrder__c'));

        Map<String,Object> borMap = ( Map<String,Object>)saveMap.get('base');
       
        for (String field :  borMap.keySet()) {

            if(borMap.get(field) == null || DataUtil.getStringValue(borMap.get(field)) == '') continue;

           if(fbeanMap.containsKey(field)) bos.put(field,  DataUtil.dataHandler(borMap.get(field),fbeanMap.get(field).type.toUpperCase() ));

        }
        if(isNew){
             bos.RecordTypeId = (String)saveMap.get('type');
             String developerName = (String)saveMap.get('name');

             if(developerName == 'PolicyWithoutContract'){
                bos.DocumentTypes__c = '库存借出';
             }else{
                bos.DocumentTypes__c = '库存其他出库';
             }
             bos.FollowupProcessing__c = '其他出入库 ';

        }

        List<Object> details = ( List<Object>)saveMap.get('datas'); 
        List<BloodSugarOrderDetail__c> bdList  = new List<BloodSugarOrderDetail__c>();
        Set<String> exsets = new Set<String>();
        for (Object o  : details) {
            Map<String,Object> mo = (Map<String,Object>)o ; 
            BloodSugarOrderDetail__c bd = new BloodSugarOrderDetail__c();
            bd.Id = DataUtil.getStringValue(mo.get('id'));
            bd.DistributionProduct__c = DataUtil.getStringValue(mo.get('eId'));
            bd.Product__c = DataUtil.getStringValue(mo.get('regentId'));
            bd.OrderNumber__c = DataUtil.getDecimalValue(mo.get('pnum'));
            bd.DistributionProductNumber__c = DataUtil.getDecimalValue(mo.get('eno'));

            bd.Reason__c = DataUtil.getStringValue(mo.get('reason'));
            bd.Remark__c = DataUtil.getStringValue(mo.get('memo'));

            bd.FuselageNumber__c = DataUtil.getStringValue(mo.get('snno'));

            if(bd.Id != null) exsets.add(bd.Id);
            bdList.add(bd);
            

        }
        SavePoint sp = Database.setSavepoint();

        try {

            if(bos.Id != null)delete [select Id from BloodSugarOrderDetail__c where Id not in: exsets and BloodSugarOrder__c=: bos.Id  ];
            upsert bos ; 
            
            for ( BloodSugarOrderDetail__c bd :bdList ) {
                if(bd.Id == null ) bd.BloodSugarOrder__c = bos.Id;  
            }
            if(bdList.size() > 0 )upsert bdList;
    
            msg = '保存成功!';
            isSuc = true;
            backId = bos.Id;
        }
        catch (Exception e) {
            Database.rollback(sp);
            if(isNew) bos.Id = null;
            msg = '保存失败:'+e.getMessage();
        }
        
        

    }

    /**
        同步NC 
        销售员借出  同步出库入申请单 后续处理方式: 其他出入库    
        客户增送   同步
        无合同     同步出库入申请单  后续处理方式: 借出
        有合同     同步预订单
        退换机  

        客户赠送、政策申请有合同、续订、换机---预订单

        销售员领用、政策申请无合同----出入库申请单

        销售员领用、政策申请无合同  后续处理方式默认为 其他出入库

        销售员领用 下游单据类型 默认为 库存其他出库
        政策申请无合同 下游单据类型  默认为 库存借出

    */
    public void syncToNc(){

        try{

           bos.PhysicalDelivery__c = EncodingUtil.urlDecode(saveJson, 'UTF-8') ;

            if(bos.Status__c != '审批成功') throw new DmlException( '未审批的血糖仪申请不能同步!');
       
            if(bos.Company__c == null)throw new DmlException( '血糖仪申请出库公司必填!');
            if(bos.Synchronization__c ==true ) throw new DmlException( '已经同步,不要重复点击!');
             //同步操作人
             User u = [select Id, ExuserCode__c from User where Id =:UserInfo.getUserId()];
             String operator = u.ExuserCode__c;


            Map<String,String >companyMap = ImportObject.getPicklistValues('Contract__c', 'Corpcode__c', false);
            String corpcode =companyMap.get(bos.Company__c);

            //出入库申请单
            List<BloodSugarOrderDetail__c> bol = [select Id ,DistributionProduct__c,DistributionProduct__r.NCCode__c ,BloodSugarOrder__c,DistributionProduct__r.Unit__c, DistributionProductNumber__c from BloodSugarOrderDetail__c where BloodSugarOrder__c =: bos.Id   ];

            Integer cnt = [select count()  from BloodSugarOrderDetail__c where BloodSugarOrder__c =: bos.Id  and  RelevantContractDetails__r.Contract__r.Status__c != '已生效'  ];

            System.debug(cnt);

           if(bos.RecordType.DeveloperName == 'SalesmenCollect' || (bos.RecordType.DeveloperName == 'PolicyWithoutContract' &&  cnt > 0) ){

                String issend = EncodingUtil.urlDecode(saveJson, 'UTF-8');

                List<Object> tmp = new List<Object>();
                
                for (BloodSugarOrderDetail__c bod  :bol ){
                     //approver = '';
                    Map<String,String> d = new Map<String,String>();

                    d.put('sfmanid', bos.Id);
                    d.put('sflistid',bod.Id);
                    d.put('cbizid',bos.Owner.Name);
                    //cdptid = ida.Owner.;
                    d.put('dbilldate',System.now().format('yyyy-MM-dd'));
                    d.put('planrecivedate',System.now().format('yyyy-MM-dd'));
                    d.put('operator', operator );
                    d.put('pk_corp',corpcode);
                    //vnote = np.Remarks__c;
                    d.put('totalnum', '0');

                    d.put('recvnotes',  bos.Address__c );
                    d.put('vnote', bos.Reason__c );
                    d.put('zdcode', bos.ReceivingCustomer__r.AccountNumber == null ? '' : bos.ReceivingCustomer__r.AccountNumber ) ;
                    d.put('isentity', issend);

                    d.put('cgphone', bos.ReceiverTelephone__c);
                    d.put('nextaction', bos.FollowupProcessing__c );
                    d.put('nextbilltype',  bos.DocumentTypes__c );
                    d.put('custcode', bos.Account__r.AccountNumber);

                    d.put('invcode',  bod.DistributionProduct__r.NCCode__c);

                    d.put('ts',  System.now().format('yyyy-MM-dd HH:mm:ss'));

                    d.put('sapply_hid',  bos.Id);

                    d.put('sapply_bid',  bod.Id);
                    d.put('isInstallsale', '否');

                    d.put('applynum',  String.valueOf(bod.DistributionProductNumber__c));
                    d.put('pk_defdoc10', '0001A1100000010658ZQ');
                    d.put('vuserdef10', '血糖仪申请');

                    tmp.add(d);

                }
                
                 bos.NCResults__c = '出入库申请单:'+ syncOutdoor(tmp);
                 bos.PhysicalDelivery__c = issend;


           }else{

                 bos.NCResults__c = '预订单:'+ preOrder(bol,operator);

           }
           bos.Synchronization__c = true ;
           update bos ;
            msg = '同步成功!';
        }catch(Exception e ){
            msg = '同步失败!'+e.getMessage();
        }
          
    }


    public String   syncOutdoor(List<Object> outdoorList){
   

            String url = Label.NCLrckInterface;

            Map<String,Object> data = new Map<String,Object>();
            data.put('data', outdoorList);

            HttpRequest req = new HttpRequest();
            req.setMethod('POST');
            req.setBody(JSON.serialize(data) );
            System.debug(JSON.serialize(data));
            req.setHeader('Content-Type','text/plain');
            //req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
            req.setEndpoint(url);
            HttpResponse res = Utils.postRequest(req, 1);
            String sycmsg = '';
             ///返回结果处理
            if (res.getStatusCode() == 200) {
                System.debug(res.getBody());
                Map<String,Object> r = null;
                  //如果是测试
                    if(Test.isRunningTest()){
                        Map<String,Object>  resBody= new Map<String,Object>();
                        resBody.put('code','0');
                        resBody.put('result','{\"result_msg\":\"UPT40088-000001\",\"result\":1}');
                        r =  resBody;
                    }else{
                        r= (Map<String,Object> ) JSON.deserializeUntyped(res.getBody());
                    }
              if(r.get('code') == 0 || r.get('code') == '0'){
                    Map<String,Object> rs = (Map<String,Object>) JSON.deserializeUntyped(((String)r.get('result')));
                    
                  if( (rs.get('result') == 1 || rs.get('result') == '1' ) ){
                        
                       return (String)r.get('result') ;

                   }else{

                      throw new DmlException( '同步出库单据失败 : '+rs.get('result_msg'));
                   }

                }else{

                     throw new DmlException( '同步出库单据失败 : '+String.valueOf(r.get('msg')));
                }

            }else{
                 throw new DmlException( '同步出库单据失败 : '+res.getBody());
            }



    }

     private  Map<String ,String> getMapfromLabel(String lbl,Boolean isReverse ){
        Map<String ,String> tmp =  new Map<String ,String>();
        List<String>  tl = lbl.split(',');
        for (String cps  :tl ) {
            List<String> cpl = cps.split('-');
            if(isReverse){
                tmp.put(cpl[1], cpl[0]);
            }else{
                tmp.put(cpl[0], cpl[1]);
            }
        }
        return tmp;

    }
 
    public String  preOrder(List<BloodSugarOrderDetail__c> bol,String operator ){

       
        Map<String,String >salesMap = getMapfromLabel(Label.Vsalestrucode,true);
        Map<String,String >scomMap = getMapfromLabel(Label.ShortCompanyName,false);
        String companycode = ImportObject.getPicklistValues('Contract__c', 'Corpcode__c', false).get(bos.Company__c);
        String scode = salesMap.get(scomMap.get(companycode));
        if(scode == null) return '请联系系统管理员维护销售组织编码!'; 

        Map<String,String> headMap = new Map<String,String>();
        headMap.put('ccurrencytypeid','CNY');
        headMap.put('ccustomerid',bos.Account__r.AccountNumber);
        headMap.put('creceiptcorpid',bos.Account__r.AccountNumber);
        headMap.put('creceiptcustomerid',bos.Account__r.AccountNumber);
        headMap.put('coperatorid',operator);

        headMap.put('csalecorpid',scode);//销售组织编码
        //headMap.put('csalecorpid','01');
        headMap.put('vnote','血糖仪申请');

        headMap.put('fstatus','1');
        headMap.put('creceipttype','38');
        headMap.put('nexchangeotobrate','1.0');
        headMap.put('pk_corp',companycode);//公司
        headMap.put('pk_defdoc6',bos.Account__r.AccountNumber);
        headMap.put('vdef6',bos.Account__r.AccountNumber+'-'+bos.Account__r.AccountNumber);
        headMap.put('vreceiveaddress', bos.Address__c);
        headMap.put('dbilldate',Utils.date2string(Date.valueOf(System.now())));
        headMap.put('dabatedate',Utils.date2string(Date.valueOf(System.now().addMonths(2))));



        if(bol.size() == 0)return '没有未同步的血糖仪申请明细!';
        ///分单
        List<Map<String,String>> bodyList = new List<Map<String,String>>();
        Integer i = 0;
        for (BloodSugarOrderDetail__c sd: bol) {
            i++;
            Map<String,String> body = new Map<String,String>();
            body.put('ccurrencytypeid','CNY' );
            body.put('crowno', String.valueOf(i));
            body.put( 'cinventoryid',sd.DistributionProduct__r.NCCode__c);//存货编码
           // body.put('cunitid',sd.DistributionProduct__r.Unit__c);//单位
            body.put('ndiscountrate','100');
            body.put('pk_corp',companycode );//公司编码
            //body.put('nnumber', '2');
            body.put('vdef4', sd.BloodSugarOrder__c );//主表pk
            body.put('vdef3', sd.Id);//子表pk 
            body.put('vdef5', 'SFXTY');//子表pk 
          
            body.put('nnumber', String.valueOf(sd.DistributionProductNumber__c));//数量


            //body.put('ntaxrate', '17');
            body.put('nmny', '0.01');
            body.put('nprice', '0.01');
            body.put('nnetprice', '0.01');
            body.put('frownote','');
            //body.put('ccalbodyid',sn.Contract__r.Vsalestrucode__c);

            bodyList.add(body);

        }


        //组装XML 
        String xml = '<ufinterface roottag="so_preorder" billtype="38" replace="Y" receiver="web" sender="web" isexchange="Y" filename="预订单表头.xml" proc="add" operation="req">';
        xml += '<so_preorder id="'+bos.Id+'" subdoctype="">';
        //组装表头
        xml+='<so_preorder_head>';
        for (String k : headMap.keySet()) {
            xml += '<' +k +'>'+headMap.get(k)+'</'+k+'>';
        }
        xml+='</so_preorder_head>';

        //组装表体
        xml+='<so_preorder_body>';
        for (Map<String,String> row : bodyList) {
            xml+='<entry>';
            for (String k : row.keySet()) {
                xml += '<' +k +'>'+row.get(k)+'</'+k+'>';
            }
            xml+='</entry>';

        }
        xml+='</so_preorder_body>';

        xml +='</so_preorder></ufinterface>';

        System.debug(xml);

        String postURL = Label.queryNCPreOrder;
        ///发送请求
        String data = EncodingUtil.urlEncode(xml,'UTF-8');
        System.debug('*** POST MD5 参数: ' + data); 
        //生成POST请求
        postURL = postURL;
        HttpRequest req = new HttpRequest(); 
        //测试 account mktest;  01;
        req.setBody('data=' + data+'&account=mktest&receiver='+companycode);
        req.setEndpoint(postURL); 
        System.debug(req.getBody());
        //POST数据到微信接口，设置编码为GB2312,防止乱码
        req.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
        req.setMethod('POST'); 
        //发送数据并取得返回结果
        HttpResponse res = Utils.postRequest(req,1); 
        //设置编码为GB2312，防止读取数据时乱码
        //res.setHeader('Content-Type','application/x-www-form-urlencoded ; charset=utf-8');
        String result = res.getBody();
        System.debug('*** : ' + result);
        if (res.getStatusCode() == 200) {


             Map<String,Object> r =null;
                 //如果是测试
                if(Test.isRunningTest()){
                  Map<String,Object>  resBody= new Map<String,Object>();
                  resBody.put('code','0');
                  /*
                {"result":"[{\"billpk\":\"\\n        \",\"bdocid\":\"a2A0k0000005HZ3EAM\",\"filename\":\"预订单表头.xml\",\"resultcode\":\"1\",\"resultdescription\":\"单据a2A0k0000005HZ3EAM开始处理...\\n单据a2A0k0000005HZ3EAM处理完毕!\",\"content\":\"业务插件返回值\"}]","code":"0","msg":"success"}
                  */
                  resBody.put('result','[{\"billpk\":\"\\n        \",\"bdocid\":\"a2A0k0000005HZ3EAM\",\"filename\":\"预订单表头.xml\",\"resultcode\":\"1\",\"resultdescription\":\"单据a2A0k0000005HZ3EAM开始处理...\\n单据a2A0k0000005HZ3EAM处理完毕!\",\"content\":\"业务插件返回值\"}]');
                    r =  resBody;
                }else{
                  r= (Map<String,Object> ) JSON.deserializeUntyped(res.getBody());
                }

             if(r.get('code') == 0|| r.get('code')=='0' ){
                List<Object> rList = (List<Object> ) JSON.deserializeUntyped(((String)r.get('result')));
                    Map<String,Object> rs = (   Map<String,Object>)rList[0];
                    if(rs.get('resultcode') == 1 || rs.get('resultcode') == '1'){
                     
                        return (String)r.get('result') ;

                    }else{
                        throw new DmlException(String.valueOf(rs.get('resultdescription'))) ;
                    }


             }else{

                throw new DmlException('接口异常,请联系系统管理员!');
             }



        }else{

            throw new DmlException( '接口异常,请联系系统管理员!');
        }
    }

    public class BloodBeanOnly{
        public String name ;//产品名称
        public String eId;//产品id 

        public Decimal eno ;//数量
        public String memo ;//备注

        public String snno ;//机身号
        public String reason ;//退机原因
         public String nccode;
        public String serialno;
        public String brand;
        public BloodBeanOnly (Product__c p  ){

            name = p.Name ; 
            eId = p.Id   ;
            nccode = p.NCCode__c;
            serialno = p.SerialNo__c;
            brand = p.Brand__c;
        
        }
        public BloodBeanOnly (ContractProduct__c p  ){

            name = p.Product__r.Name ; 
            eId = p.Product__c    ;
            nccode = p.Product__r.NCCode__c;
            serialno = p.Product__r.SerialNo__c;
            brand = p.Product__r.Brand__c;
        
        }
        public BloodBeanOnly (BloodSugarOrderDetail__c bsd ){
            name = bsd.DistributionProduct__r.Name ; 
            eId = bsd.DistributionProduct__c;
            eno = bsd.DistributionProductNumber__c;
            snno = bsd.FuselageNumber__c;
            reason = bsd.Reason__c;
             nccode = bsd.DistributionProduct__r.NCCode__c;
            serialno = bsd.DistributionProduct__r.SerialNo__c;
            brand = bsd.DistributionProduct__r.Brand__c;

            memo = bsd.Remark__c;

        }


    }

    public class BloodBean{

        public String name ; 
        public String eId;
        public Decimal eno; 
        public Decimal pnum ; 
        public String id ; 
        public String regentId; 
        public String regentName ; 
        public Decimal regentCount;
        public Decimal maxeNum;
        public Decimal zl ;
        public String nccode;
        public String serialno;
        public String brand;
        public String memo ;//备注

        public BloodBean (BloodSugarOrderDetail__c bsd ){

            name = bsd.DistributionProduct__r.Name ; 
           eId = bsd.DistributionProduct__c;
            eno = bsd.DistributionProductNumber__c;

            pnum = bsd.OrderNumber__c;
            id = bsd.Id;
            regentId = bsd.Product__c ; 
            regentName = bsd.Product__r.Name;

            regentCount = bsd.CountT__c;
            maxeNum = bsd.DistributionMax__c;
            zl = Decimal.valueOf(bsd.Product__r.zl__c);
            nccode = bsd.DistributionProduct__r.NCCode__c;
            serialno = bsd.DistributionProduct__r.SerialNo__c;
            brand = bsd.DistributionProduct__r.Brand__c;
            memo = bsd.Remark__c;

        }

        public BloodBean (Product__c bsd,Product__c p  ){

            name = bsd.Name ; 
            eId = bsd.Id   ;
            nccode = bsd.NCCode__c;
            serialno = bsd.SerialNo__c;
            brand = bsd.Brand__c;

            if(p != null )regentId = p.Id  ; 
            if(p != null )regentName = p.Name ;

            if(p!= null )zl = Decimal.valueOf(p.zl__c);

        }

       

    }







}